#pragma once

#include "Singleton.h"
#include "FrameWorker.h"
#include "rank/RBTreeRank.h"

class RankMgr : public FrameWorker, public AsyncTaskOwner, public Singleton<RankMgr>
{
public:
	THREAD_RUNTIME(RankMgr)

	RankMgr();
	virtual ~RankMgr();

	virtual void Update(uint64 diffTime);

	void ClearAllPlayerRankData();
	void ClearAllGuildRankData();

	GErrorCode HandleNewPlayer(INetPacket& pck);
	GErrorCode HandleUpdatePlayer(INetPacket& pck);
	GErrorCode HandleRemovePlayer(INetPacket& pck);

	GErrorCode HandleNewGuild(INetPacket& pck);
	GErrorCode HandleUpdateGuild(INetPacket& pck);
	GErrorCode HandleRemoveGuild(INetPacket& pck);

	GErrorCode HandleGetPlayerRankList(Coroutine::YieldContext& ctx,
		uint32 playerId, uint8 subType, uint32 startIndex, uint32 getCountMax);
	GErrorCode HandleGetGuildRankList(Coroutine::YieldContext& ctx,
		uint32 playerId, uint32 guildId, uint8 subType, uint32 startIndex, uint32 getCountMax);

	GErrorCode HandlePackGuildRankIdList(
		INetPacket& pck, uint8 subType, uint32 startIndex, uint32 getCountMax);

private:
	RankData4Player* GetRankData4Player(uint32 playerId) const;
	static void PackRankData4Player(INetPacket& pck, const RankData4Player* pRankData, uint8 subType);

	RankData4Guild* GetRankData4Guild(uint32 playerId) const;
	static void PackRankData4Guild(INetPacket& pck, const RankData4Guild* pRankData, uint8 subType);

	std::vector<RBTreeRank<uint32, RankData4Player*>> m_rank4Player;
	std::unordered_map<uint32, RankData4Player*> m_rankData4Player;

	std::vector<RBTreeRank<uint32, RankData4Guild*>> m_rank4Guild;
	std::unordered_map<uint32, RankData4Guild*> m_rankData4Guild;

public:
	struct Packet {
		enum Type {
			Client,
			Server,
		};
		Type type;
		union {
			uint32 uid;
		};
		INetPacket* pck = NULL;
	};
	static Packet NewClientPacket(uint32 uid, INetPacket* pck);
	static Packet NewServerPacket(INetPacket* pck);
	void PushRecvPacket(const Packet& packet);
private:
	void UpdateAllPackets();
	int HandleOneRecvPacket(const Packet& packet);
	int HandleOneRecvClientPacket(const Packet& packet);
	int HandleOneRecvServerPacket(const Packet& packet);
	MultiBufferQueue<Packet, 1024> m_PacketStorage;
};

#define sRankMgr (*RankMgr::instance())
